
#include "stdafx.h"
#include "DB_SQLite.h"
#include "Log_SQLite.h"
#include "comutil.h"
#include "win32/CharacterSet.h"

#define DEFAULT_LOGFILE_NAME _T("Log_SQLite.log")
#define DEFAULT_LOGDIRECTORY _T("db")
#define MAX_BUFFER_NUM 512


////////////////////////////////////////////////////////////////////////////////////////////////////
CSQLiteBase::CSQLiteBase()
{
	m_LogCallBack = NULL;
	m_WorkDirectory.Empty();
	m_LogFileName.Empty();
	m_IsOpen = false;
	SetWorkDirectory((DEFAULT_LOGDIRECTORY));
	SetLiteLogName((DEFAULT_LOGFILE_NAME));
}

////////////////////////////////////////////////////////////////////////////////////////////////////
CSQLiteBase::~CSQLiteBase()
{
}


////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::OpenFullPath(const char* FileName)
{
	if(FileName==NULL)
	{
		WriteSQLLog(1,CString("filename null error!"));
		return false;
	}
	try
	{
		m_db.close();
		m_db.open(FileName);
		m_IsOpen = true;
	}
	catch(CppSQLite3Exception ex)
	{
		m_IsOpen = false;
		CString Log;
		Log.Format("Open Error!");
		WriteSQLLog(1,Log);
		return false;
	}
	return m_IsOpen;

}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Open(const char* FileName)
{
	if(FileName==NULL)
	{
		WriteSQLLog(1,CString("filename null error!"));
		return false;
	}
	try
	{

		m_db.open(FileName);
		m_IsOpen = m_db.dbExists();
	}
	catch(CppSQLite3Exception ex)
	{
		m_IsOpen = false;
		CString Log;
		Log.Format("Open Error!");
		WriteSQLLog(1,Log);
		return false;
	}
	return m_IsOpen;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void CSQLiteBase::Close()
{
	m_db.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void CSQLiteBase::SetWorkDirectory(const char* Directory)
{
	m_WorkDirectory = Directory;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void CSQLiteBase::SetLiteLogName(const char* LogName)
{
	if(LogName==NULL)
		return;

	if(m_WorkDirectory.IsEmpty())
	{
		m_LogFileName += DEFAULT_LOGDIRECTORY;	
	}
	else
	{
		m_LogFileName += m_WorkDirectory;
	}
	m_LogFileName +="\\";
	m_LogFileName += LogName;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void CSQLiteBase::WriteSQLLog(int i , const char* szLogError)
{

	if(m_LogCallBack!=NULL)
		m_LogCallBack(i,szLogError);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::IsOpen()
{
	return this->m_IsOpen;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::BeginSqlCommit(SQLiteList& test)
{
	int i = 0;
	try
	{
		GetDB()->execDML("begin transaction;");

		for (i = 0; i <(int)test.size(); i++)
		{
			CString str = test[i];

			GetDB()->execDML((const char*)test[i]);
		}


		GetDB()->execDML("commit transaction;");
		return true;
	}
	catch(CppSQLite3Exception& ex)
	{
		GetDB()->execDML("commit transaction;");
		WriteSQLLog(1,ex.errorMessage());
		throw i;// throw out the error sql command , so out
		return false;
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Transcode(const char* Source, unsigned short& numRet)
{
	CString strRet;
	if (Transcode(Source, strRet) != NULL)
	{
		numRet = atoi(strRet.GetBuffer());
		return true;
	}
	else
	{
		numRet = 0;
	}
	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Transcode(const char* Source, short& numRet)
{
	CString strRet;
	if (Transcode(Source, strRet) != NULL)
	{
		numRet = atoi(strRet.GetBuffer());
		return true;
	}
	else
	{
		numRet = 0;
	}
	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Transcode(const char* Source, int& numRet)
{
	CString strRet;
	if (Transcode(Source, strRet) != NULL)
	{
		numRet = atoi(strRet.GetBuffer());
		return true;
	}
	else
	{
		numRet = 0;
	}
	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Transcode(const char* Source, unsigned int& numRet)
{
	CString strRet;
	if (Transcode(Source, strRet) != NULL)
	{
		numRet = atoi(strRet.GetBuffer());
		return true;
	}
	else
	{
		numRet = 0;
	}
	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CSQLiteBase::Transcode(const char* Source, bool& flagRet)
{
	int num;
	if (Transcode(Source, num) == true)
	{
		return (num != 0);
	}
	return false;
}

const char* CSQLiteBase::NoTranscode(const char* Source,CString& strRet)
{
	int len =0; 
	strRet.Empty();
	if (Source == NULL)
	{

		return NULL;
	}
	try
	{
		strRet = Source ;
	}
	catch(...)
	{
		return NULL;
	}
    return (const char*)strRet;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
const char* CSQLiteBase::Transcode(const char* Source,CString& strRet)
{
	int len =0; 
	strRet.Empty();
	if (Source == NULL)
	{

		return NULL;
	}
	try
	{
		std::string newStr;
		CharacterSet::ConvertUTF8ToASCII(Source, newStr);
		strRet = newStr.c_str();
	}
	catch(...)
	{
		return NULL;
	}
    return (const char*)strRet;
}

bool CSQLiteBase::Transcode(const char* Source,string& strRet)
{
	if (Source == NULL)
	{
		return false;
	}
	try
	{
		CharacterSet::ConvertUTF8ToASCII(Source, strRet);
		return true;
	}
	catch(...)
	{
		return false;
	}
	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
CDBSQLite::CDBSQLite(void)
{
}


////////////////////////////////////////////////////////////////////////////////////////////////////
CDBSQLite::~CDBSQLite(void)
{

}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CDBSQLite::DBQueryTableField(const char* sFieldName, const char* sCondition, CString& strRet)
{

   if(!IsOpen())
		return false;

   if(m_TableName.IsEmpty())
	   return false;

   CString strSQL ;

   if(sCondition==NULL)
	   strSQL.Format("select %s from %s",sFieldName,(const char*)m_TableName);
   else
	   strSQL.Format("select %s from %s where %s",sFieldName,(const char*)m_TableName,sCondition);

   try
   {
   		SQLiteDBQuery q = GetDB()->execQuery((const char*)strSQL);
		if(q.eof())
			return false;
		else
		{
			Transcode(q.fieldValue(0),strRet);
			return true;
		}
   }
   catch(CppSQLite3Exception& ex)
   {
	   this->WriteSQLLog(1,ex.errorMessage());
	   return false;
   }

}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CDBSQLite::DBQueryTableFieldList(const char* sFieldName, const char* sCondition, CDBSQLite::SQLiteList& strRetList)
{
	if(!IsOpen())
		return false;
	if(m_TableName.IsEmpty())
		return false;

	CString strSQL ;

	if(sCondition==NULL)
		strSQL.Format("select %s from %s",sFieldName,(const char*)m_TableName);
	else
		strSQL.Format("select %s from %s where %s",sFieldName,(const char*)m_TableName,sCondition);
	SQLiteDBQuery q = GetDB()->execQuery((const char*)strSQL);
	if(q.eof())
		return false;
	else
	{
		CString strRet;
		while(!q.eof())
		{
			Transcode(q.fieldValue(0),strRet);
			strRetList.push_back(strRet);
			q.nextRow();
		}
		return true;
	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int CDBSQLite::DBQueryTableCount()
{
	if(!IsOpen())
		return false;
	if(m_TableName.IsEmpty())
		return false;
	const char * sTemp = "select count(*) from %s";
	CString strSQL;
	strSQL.Format(sTemp,(const char*)m_TableName);
	return GetDB()->execScalar((const char*)strSQL); 
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CDBSQLite::SetTableName(const char* szTableName)
{
	m_TableName = szTableName;
	try
	{
		if(GetDB()->tableExists(szTableName))
			return true;
		else
			return false;
	}
	catch(...)
	{
		m_TableName.Empty();
		return false;
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
bool CDBSQLite::ExecuteSQL(const char* szSQLCommand)
{
	int retValue = 0;
	try
	{
		retValue = GetDB()->execDML(szSQLCommand);
		return retValue>0;
	}
	catch(CppSQLite3Exception& ex)
	{
		WriteSQLLog(1,ex.errorMessage());
		return false;
	}
}


